package com.example.elasticsearch;

import com.example.elasticsearch.entity.Goods;
import com.example.elasticsearch.mapper.GoodsMapper;
import com.example.elasticsearch.mapper.GoodsRepository;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilterBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SourceFilter;
import org.springframework.test.context.junit4.SpringRunner;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

/**
 * 必须添加类描述
 *
 * @author HTJT
 * @date 2023/3/7 15:11
 * @version 1.0
 */
@SpringBootTest
@RunWith(SpringRunner.class)
public class highlight {

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private GoodsRepository goodsRepository;

    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * 高亮查询
     */
    @Test
    public void highlightBuilder() {
        //查询条件(词条查询：对应ES query里的match)
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "三星手机");

        //设置高亮三要素                                    field: 你的高亮字段    // preTags ：前缀    // postTags：后缀
        HighlightBuilder highlightBuilder = new HighlightBuilder().field("title").preTags("<font color='red'>").postTags("</font>");
        //创建查询条件构建器SearchSourceBuilder(对应ES外面的大括号)
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
                .withQuery(matchQueryBuilder)
                .withHighlightBuilder(highlightBuilder)
                .build();

        //查询,获取查询结果
        SearchHits<Goods> search = elasticsearchRestTemplate.search(nativeSearchQuery, Goods.class);

        //获取总记录数
        System.out.println("totalHits = " + search.getTotalHits());
        //获取值返回

        search.getSearchHits().stream().map(searchHit -> {
            //获得结果实体
            Goods goods = searchHit.getContent();
            //所有高亮结果
            Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
            //遍历高亮结果
            for (Map.Entry<String, List<String>> stringListEntry : highlightFields.entrySet()) {
                String key = stringListEntry.getKey();
                //获取实体反射类
                Class<?> aClass = goods.getClass();
                try {
                    //获取该实体属性
                    Field declaredField = aClass.getDeclaredField(key);
                    //权限为私的 解除！
                    declaredField.setAccessible(true);
                    //替换，把高亮字段替换到这个实体对应的属性值上
                    declaredField.set(goods, stringListEntry.getValue().get(0));
                } catch (NoSuchFieldException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            return goods;
        }).forEach(System.out::println);
    }


}
